package mailx

import (
	"net/mail"
	"strings"
)

type (
	AddressList []*Address
	Address     struct {
		Name    string `json:"name,omitempty"`
		Address string `json:"address,omitempty"`
	}
)

func (a *Address) String() string {
	if a == nil || (a.Name == "" && a.Address == "") {
		return ""
	}
	return ((*mail.Address)(a)).String()
}

func (a *Address) Set(address string, name ...string) {
	a.Address = address
	for _, name := range name {
		if name != "" {
			a.Name = name
			break
		}
	}
}

func (l *AddressList) Add(address ...string) (err error) {
	var list AddressList
	if list, err = ParseAddressList(address...); err != nil {
		return err
	}
	l.AddAddress(list...)
	return
}

func (l *AddressList) AddOne(address string, name ...string) {
	a := &Address{}
	a.Set(address, name...)
	l.AddAddress(a)
}

func (l *AddressList) AddAddress(addrs ...*Address) {
	*l = append(*l, addrs...)
}

func (l *AddressList) Purge() {
	*l = (*l)[:0]
}

func (l *AddressList) Rcpts() []string {
	return sliceMap(*l, func(it *Address) (string, bool) {
		if it != nil && it.Address != "" {
			return it.Address, true
		}
		return "", false
	})
}

func (l *AddressList) Text() []string {
	return sliceMap(*l, func(it *Address) (string, bool) {
		if it != nil && it.Address != "" {
			return it.String(), true
		}
		return "", false
	})
}

func (l *AddressList) String() string {
	return strings.Join(l.Text(), ",")
}

func (l *AddressList) At(index int) (find *Address) {
	if index < len(*l) {
		find = (*l)[index]
	}
	return
}

func ParseAddressList(addressList ...string) (out AddressList, err error) {
	var all, tmp []*mail.Address
	for _, s := range addressList {
		if tmp, err = mail.ParseAddressList(s); err != nil {
			return
		}
		all = append(all, tmp...)
	}
	out = sliceMap(all, func(it *mail.Address) (*Address, bool) { return (*Address)(it), true })
	return
}
